package concurrent;

public class ProducerConsumer {
    public static void main(String[] args) {
        ProducerConsumer p = new ProducerConsumer();
        Thread p1 = new Thread(new Producer(p), "sc-1");
        Thread p2 = new Thread(new Producer(p), "sc-2");
        Thread p3 = new Thread(new Producer(p), "sc-3");
        Thread c1 = new Thread(new Consumer(p), "xf-1");
        Thread c2 = new Thread(new Consumer(p), "xf-2");
        Thread c3 = new Thread(new Consumer(p), "xf-3");
        p1.start();
        p2.start();
        p3.start();
        c1.start();
        c2.start();
        c3.start();
    }

    int a = 0;

    public synchronized void increase() throws InterruptedException {
        while (a == 100) {
            wait();
        }
        a++;
        Thread.sleep(100);
        System.out.println(Thread.currentThread().getName() + " increase -- " + a);
        notifyAll();
    }

    public synchronized void decrease() throws InterruptedException {
        while (a == 0) {
            wait();
        }
        a--;
        Thread.sleep(100);
        System.out.println(Thread.currentThread().getName() + " decrease -- " + a);
        notifyAll();
    }

}

class Producer implements Runnable {
    ProducerConsumer p;

    public Producer(ProducerConsumer p) {
        this.p = p;
    }

    @Override
    public void run() {
        while (true) {
            try {
                p.increase();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

class Consumer implements Runnable {
    ProducerConsumer p;

    public Consumer(ProducerConsumer p) {
        this.p = p;
    }

    @Override
    public void run() {
        while (true) {
            try {
                p.decrease();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}